package com.leo.chapter10;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.HashSet;
import java.util.Set;

/**
 *
 * @author xuexiaolei
 * @version 2017年10月18日
 */
public class OpenCall {
    class Taxi{
        private Point location, destination;
        private final Dispatcher dispatcher;

        Taxi(Dispatcher dispatcher) {
            this.dispatcher = dispatcher;
        }

        public synchronized Point getLocation(){
            return location;
        }

        /**
         * 先锁自己taxi，再锁dispatcher
         * 与下面类的getImage可能造成死锁
         */
        public synchronized void setLocation(Point location){
            this.location = location;
            if (location.equals(destination)){
                dispatcher.notifyAvaliable(this);
            }
        }

        /**
         * 上面方法修改为Open Call模式，开放调用模式
         */
        public void setLocation2(Point location){
            boolean reachedDestionation;
            synchronized (this) {
                this.location = location;
                reachedDestionation = location.equals(destination);
            }
            if (reachedDestionation){
                dispatcher.notifyAvaliable(this);
            }
        }
    }

    class Dispatcher{
        private final Set<Taxi> taxis;
        private final Set<Taxi> availableTaxis;

        Dispatcher() {
            taxis = new HashSet<>();
            availableTaxis = new HashSet<>();
        }

        public synchronized void notifyAvaliable(Taxi taxi) {
            availableTaxis.add(taxi);
        }

        /**
         * 先锁自己dispatcher，再锁一个个的taxi
         */
        public synchronized Image getImage(){
            Image image = new BufferedImage(1,2,2);
            for (Taxi t : taxis){
//                image.drawMarker(t.getLocation());
            }
            return image;
        }

        /**
         * 上面方法修改为Open Call模式，开放调用模式
         */
        public Image getImage2(){
            Set<Taxi> copy;
            synchronized (this){
                copy = new HashSet<>(taxis);
            }
            Image image = new BufferedImage(1,2,2);
            for (Taxi t : copy){
                //                image.drawMarker(t.getLocation2());
            }
            return image;
        }
    }
}
